package com.jiangyg.devtools.ui.table;

import com.intellij.openapi.project.Project;
import com.intellij.ui.table.JBTable;
import com.jiangyg.devtools.DevtoolsException;
import com.jiangyg.devtools.toolkit.CacheUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

import javax.swing.*;
import javax.swing.table.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

/**
 * 类描述：可编辑表格
 *
 * @author jiangyg
 * @date 2023-08-26
 */
public class EditableTable extends JBTable {

    private final String name;

    private final Project project;

    public EditableTable(String name, TableModel tableModel, Project project) {
        super(tableModel);
        this.name = name;
        this.project = project;
        // 初始化操作
        initialization();
    }

    /**
     * 功能描述：初始化操作
     */
    private void initialization() {
        // 初始化表格配置
        initTableConfig();
        // 初始化表格头配置
        initTableHeaderConfig();
        // 初始化表格体配置
        initTableBodyConfig();
        // 初始化表格头宽度
        initTableHeaderWidth();
    }

    /**
     * 功能描述：初始化表格配置
     */
    private void initTableConfig() {
        // 设置行选中模式
        this.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
//        this.setSelectionMode(DefaultListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        // 设置行高
        this.setRowHeight(28);
    }

    /**
     * 功能描述：初始化表格头配置
     */
    private void initTableHeaderConfig() {
        // 不允许表头拖动
        final JTableHeader tableHeader = this.getTableHeader();
        tableHeader.setReorderingAllowed(false);
        // 表头标题居中
        final DefaultTableCellRenderer defaultTableCellRenderer = new DefaultTableCellRenderer();
        defaultTableCellRenderer.setHorizontalAlignment(DefaultTableCellRenderer.CENTER);
        tableHeader.setDefaultRenderer(defaultTableCellRenderer);
        // 表头拖动事件
        tableHeaderDraggedEvent(tableHeader);
    }

    /**
     * 功能描述：初始化表格头宽度
     */
    private void initTableHeaderWidth() {
        try {
            final List<ColumnWidth> tableColumnWidth = CacheUtils.getTableColumnWidth(name);
            if (CollectionUtils.isEmpty(tableColumnWidth)) {
                return;
            }
            final Enumeration<TableColumn> columns = EditableTable.this.getColumnModel().getColumns();
            columns.asIterator().forEachRemaining(column -> {
                tableColumnWidth.stream()
                        .filter(tcw -> StringUtils.equals(String.valueOf(column.getHeaderValue()), tcw.getName()))
                        .findAny()
                        .ifPresent(tcw -> column.setPreferredWidth(tcw.getWith()));
            });
        } catch (Exception ex) {
            throw new DevtoolsException(String.format("初始化表格[%s]列宽出错", name), ex);
        }
    }

    /**
     * 功能描述：表格头拖动事件
     *
     * @param tableHeader 表格头
     */
    private void tableHeaderDraggedEvent(JTableHeader tableHeader) {
        tableHeader.addMouseMotionListener(new MouseAdapter() {

            @Override
            public void mouseDragged(MouseEvent e) {
                final List<ColumnWidth> columnWidthList = new ArrayList<>();

                final Enumeration<TableColumn> columns = EditableTable.this.getColumnModel().getColumns();
                final Iterator<TableColumn> iterator = columns.asIterator();
                while (iterator.hasNext()) {
                    final TableColumn tableColumn = iterator.next();

                    final ColumnWidth columnWidth = new ColumnWidth();
                    columnWidth.setName(tableColumn.getHeaderValue().toString());
                    columnWidth.setWith(tableColumn.getWidth());

                    columnWidthList.add(columnWidth);
                }

                CacheUtils.setTableColumnWidth(name, columnWidthList);
            }

        });
    }

    /**
     * 功能描述：初始化表格体配置
     */
    private void initTableBodyConfig() {
        try {
            final AbstractEditableTableModel tableModel = (AbstractEditableTableModel) this.getModel();
            for (int columnIndex = 0; columnIndex < this.getColumnModel().getColumnCount(); columnIndex++) {
                final TableColumn column = this.getColumnModel().getColumn(columnIndex);
                final ColumnDefinition definition = tableModel.getColumnDefinition(columnIndex);

                final Class<? extends TableCellRenderer> render = definition.getRender();
                if (render != null) {
                    column.setCellRenderer(render.getConstructor().newInstance());
                }

                final Class<? extends TableCellEditor> editor = definition.getEditor();
                if (editor != null && definition.isEditable()) {
                    column.setCellEditor(editor.getConstructor(Project.class).newInstance(project));
                }
            }
        } catch (Exception ex) {
            throw new DevtoolsException("编辑表格的单元格设置出错，", ex);
        }
    }

}
